package net.sxnic.workflow.task;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import net.sxinfo.core.entity.AbstractEntity;
import net.sxnic.item.mdata.Mdata;
import net.sxnic.workflow.node.Node;

import org.hibernate.annotations.BatchSize;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;

/**
 * 
 * 项目申报专用工作系统
 * @version v1.0
 * @author yfsun：孙宇飞
 * 
 */
@Entity
@Table(name = "wf_task")
@BatchSize(size = 10)
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Task extends AbstractEntity {

	private static final long serialVersionUID = 7772590535733309061L;

	/**
	 * 任务状态：正常状态。
	 */
	public static final String TASK_STATUS_ACTIVE = "active";

	/**
	 * 任务状态：挂起状态。
	 */
	public static final String TASK_STATUS_SUSPENDED = "suspended";

	/**
	 * 任务状态：取消状态。
	 */
	public static final String TASK_STATUS_CANCELED = "canceled";

	/**
	 * 任务状态：结束状态。
	 */
	public static final String TASK_STATUS_ENDED = "ended";

	/**
	 * 任务状态：逻辑删除状态。
	 */
	public static final String TASK_STATUS_DELETED = "deleted";

	/**
	 * 任务状态 : 退回
	 */
	public static final String TASK_STATUS_RETURNBACK = "returnback";

	/**
	 * 任务被退回之后，继续的方式。直接跳到被退回的节点。
	 */
	public static final String RETURNBACK_CONTINUE_TYPE_GOTOFROM = "gotofrom";

	/**
	 * 任务被退回之后，继续的方式。重新走当前节点之后的所有流程。
	 */
	public static final String RETURNBACK_CONTINUE_TYPE_CONTINUE = "continue";

	/**
	 * 类型，申报系统中的大类别
	 */
	@Column(length=30)
	private String processName;

	/**
	 * 任务名称，一般为节点名称。
	 */
	@Column(length=30)
	private String name;
	
	/**
	 * 选中的Transition名字
	 */
	@Column(length=20)
	private String trs;
	
	/**
	 * 任务所对应Mdata是不是最后一条 ，非正常情况下的来回修改，提交将产生n条任务，而在任务列表中显示显示多条是不合适的，所以增加次字段，来区分
	 */
	private boolean lastOne;

	/**
	 * 任务的承办者,这是承办者是虚的，申报单位或申报人的userName ，管理单位的deptCode
	 */
	@Column(length=30)
	private String assignee;
	
	/**
	 * 审核人，申报单位或申报人的fullName ，管理单位的具体办理人默认为deptName，可以自己填
	 */
	@Column(length=20)
	private String verifier;

	/**
	 * 结束时间
	 */
	private Date endDate;

	/**
	 * 限定最迟办理时间
	 */
	private Date dueDate;

	/**
	 * 状态。正常状态：active；挂起：suspended；取消：canceled；结束：ended；逻辑删除：deleted。
	 */
	@Column(length=10)
	private String status;

	/**
	 * 任务的非执行者，如管理员
	 */
	@Column(length=10)
	private String outcomeOperator;

	/**
	 * 任务的非执行者操作时间，如管理员取消此任务的操作时间
	 */
	private Date outcomeOperateDate;

	/**
	 * 任务的非执行者，修改此任务的原因
	 */
	@Column(length=200)
	private String outcomeOperateReason;

	/**
	 * 意见
	 */
	@Lob 
	private String comments;

	/**
	 * 任务执行人的所在处室，便于在任务列表中显示
	 */
	@Column(length=20)
	private String dept;

	/**
	 * 标记此任务是否被退回的任务
	 */
	private boolean returnBack;

	/**
	 * 被退回之后，任务继续的方式。1 gotoFrom 2 continue
	 */
	@Column(length=20)
	private String continueType;

	/**
	 * 如果是被退回，此属性记录 被退回的操作人
	 */
	@Column(length=20)
	private String returnBackFromMan;

	/**
	 * 如果是被退回，此属性记录 被退回的节点
	 */
	@Column(length=20)
	private String returnBackFromNode;

	/**
	 * 委托脚本，如果是委托任务，此任务是委托发起人，则dest_xxx,如果此任务是委托的执行人,则用from_xxx。
	 * 如果是被委托人办理之前发起人自己收回了委托，则此脚本用regain_commissionId_收回日期
	 */
	@Column(length=100)
	private String commissionScript;

	/**
	 * 人员排名
	 */
	private int userOrder;
	
	@Column(length=30)
	private String str1;
	@Column(length=30)
	private String str2;
	@Column(length=30)
	private String str3;
	@Column(length=30)
	private String str4;
	@Column(length=30)
	private String str5;

	@ManyToOne(fetch = FetchType.LAZY)
	@Cascade(value = { CascadeType.REFRESH})
	@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
	private Node node;
	
	@ManyToOne(fetch = FetchType.LAZY)
	@Cascade(value = { CascadeType.REFRESH})
	@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
	private Mdata mdata;
	
	@ManyToOne(fetch = FetchType.LAZY)
	@Cascade(value = { CascadeType.REFRESH})
	@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
	private Task fromTask;

	public Task() {
		super();
		this.status = Task.TASK_STATUS_ACTIVE;
		this.returnBack = false;		
		mdata = new Mdata();
		this.lastOne=true;
	}

	public Task(String name, String assignee) {
		super();
		this.name = name;
		this.assignee = assignee;
		this.status = Task.TASK_STATUS_ACTIVE;
		this.returnBack = false;		
		mdata = new Mdata();
		this.lastOne=true;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getAssignee() {
		return assignee;
	}

	public void setAssignee(String assignee) {
		this.assignee = assignee;
	}

	public Date getEndDate() {
		return endDate;
	}

	public void setEndDate(Date endDate) {
		this.endDate = endDate;
	}

	public String getOutcomeOperator() {
		return outcomeOperator;
	}

	public void setOutcomeOperator(String outcomeOperator) {
		this.outcomeOperator = outcomeOperator;
	}

	public String getComments() {
		return comments;
	}

	public void setComments(String comments) {
		this.comments = comments;
	}

	public Date getOutcomeOperateDate() {
		return outcomeOperateDate;
	}

	public void setOutcomeOperateDate(Date outcomeOperateDate) {
		this.outcomeOperateDate = outcomeOperateDate;
	}

	public Date getDueDate() {
		return dueDate;
	}

	public void setDueDate(Date dueDate) {
		this.dueDate = dueDate;
	}

	public String getStatus() {
		return status;
	}

	public void setStatus(String status) {
		this.status = status;
	}

	@Override
	public String toString() {
		if(fromTask !=null){
			return " name :" + name + " processName :" + processName + " fromNode :" + this.fromTask.getName() + " fromAssignee : "
					+ this.fromTask.getAssignee() + " assignee :" + assignee + " entityId : " +mdata.getId() ;
		}else{
			return " name :" + name + " processName :" + processName  + " assignee :" + assignee + " entityId : " +mdata.getId() ;
		}
		
	}

	public String getProcessName() {
		return processName;
	}

	public void setProcessName(String processName) {
		this.processName = processName;
	}

	public boolean isEnded() {
		if (TASK_STATUS_ENDED.equals(this.getStatus()) && this.getEndDate() != null) {
			return true;
		} else {
			return false;
		}
	}

	public boolean isActived() {
		if (TASK_STATUS_ACTIVE.equals(this.getStatus()) && this.getEndDate() == null) {
			return true;
		} else {
			return false;
		}
	}

	public String getOutcomeOperateReason() {
		return outcomeOperateReason;
	}

	public void setOutcomeOperateReason(String outcomeOperateReason) {
		this.outcomeOperateReason = outcomeOperateReason;
	}

	public boolean isReturnBack() {
		return returnBack;
	}

	public void setReturnBack(boolean returnBack) {
		this.returnBack = returnBack;
	}

	public String getReturnBackFromMan() {
		return returnBackFromMan;
	}

	public void setReturnBackFromMan(String returnBackFromMan) {
		this.returnBackFromMan = returnBackFromMan;
	}

	public String getReturnBackFromNode() {
		return returnBackFromNode;
	}

	public void setReturnBackFromNode(String returnBackFromNode) {
		this.returnBackFromNode = returnBackFromNode;
	}

	public String getContinueType() {
		return continueType;
	}

	public void setContinueType(String continueType) {
		this.continueType = continueType;
	}

	public String getDept() {
		return dept;
	}

	public void setDept(String dept) {
		this.dept = dept;
	}

	public String getCommissionScript() {
		return commissionScript;
	}

	public void setCommissionScript(String commissionScript) {
		this.commissionScript = commissionScript;
	}
	
	public Node getNode() {
		return node;
	}

	public void setNode(Node node) {
		this.node = node;
	}

	public int getUserOrder() {
		return userOrder;
	}

	public void setUserOrder(int userOrder) {
		this.userOrder = userOrder;
	}

	public Task getFromTask() {
		return fromTask;
	}

	public void setFromTask(Task fromTask) {
		this.fromTask = fromTask;
	}

	public Mdata getMdata() {
		return mdata;
	}

	public void setMdata(Mdata mdata) {
		this.mdata = mdata;
	}

	public String getStr1() {
		return str1;
	}

	public void setStr1(String str1) {
		this.str1 = str1;
	}

	public String getStr2() {
		return str2;
	}

	public void setStr2(String str2) {
		this.str2 = str2;
	}

	public String getStr3() {
		return str3;
	}

	public void setStr3(String str3) {
		this.str3 = str3;
	}

	public String getStr4() {
		return str4;
	}

	public void setStr4(String str4) {
		this.str4 = str4;
	}

	public String getStr5() {
		return str5;
	}

	public void setStr5(String str5) {
		this.str5 = str5;
	}

	public String getVerifier() {
		return verifier;
	}

	public void setVerifier(String verifier) {
		this.verifier = verifier;
	}

	public String getTrs() {
		return trs;
	}

	public void setTrs(String trs) {
		this.trs = trs;
	}

	public boolean isLastOne() {
		return lastOne;
	}

	public void setLastOne(boolean lastOne) {
		this.lastOne = lastOne;
	}

}
